package com.free.mini.common.utils;

import java.util.UUID;

import org.apache.commons.lang3.RandomUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.skywalking.apm.toolkit.trace.TraceContext;

import lombok.extern.slf4j.Slf4j;

/**
 * skywalking
 * @version 1.0.0
 *
 */
@Slf4j
public class BizTraceUtil {

	public static final String UNKNOWN = "unknown";
	public static final String HYPHEN = "-";
	public static final String DOT=".";
	public static final String BIZ_TRACE_ID = "biz-trace-id";

	public static final String SPRING_APPLICATION_NAME = "spring.application.name";
	private static String appName;

	/**
	 * 开启链路
	 */
	public static void openDefaultTrace(String applicationName) {
		log.debug("applicationName = {}", applicationName);
		openTrace(applicationName, null);
	}

	/**
	 * 承接上游 trace id
	 * 
	 * @param traceId
	 */
	public static void openTrace(String applicationName, String traceId) {
		log.debug("applicationName = {}", applicationName);
		appName = applicationName;
		if (StringUtils.isBlank(traceId)) {
			traceId = generateTraceId();
		}
		if (traceId != null && traceId.equals(Thread.currentThread().getName())) {
			return;
		}
		String threadName = Thread.currentThread().getName();
		log.debug("thread rename, from: {} to: {}", threadName, traceId);
		Thread.currentThread().setName(traceId);
	}

	/**
	 * 当前 trace id
	 * 
	 * @return
	 */
	public static String currentTraceId() {
		return Thread.currentThread().getName();
	}

	public static String generateTraceId() {
		String applicationName = appName;
		if (StringUtils.isBlank(applicationName)) {
			applicationName = System.getProperty(SPRING_APPLICATION_NAME);
		}
		if (StringUtils.isBlank(applicationName)){
			applicationName = UNKNOWN;
		}
		String skTrace = TraceContext.traceId();
		if(StringUtils.isEmpty(skTrace) || !skTrace.contains(DOT)){
			StringBuilder uuid = new StringBuilder(UUID.randomUUID().toString()).append("_").append(RandomUtils.nextLong());
			skTrace = uuid.toString().replaceAll(HYPHEN, "");
		}
		return applicationName.concat("_").concat(skTrace);
	}
}